home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / ncd-0.000 / ncd-0 / ncd-0.9.8 / ncd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-06  |  8.9 KB  |  459 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <getopt.h>
  6. #include <signal.h>
  7.  
  8. #include "ncd.h"
  9.  
  10. /*************************************************************************/
  11.  
  12. void cleanUp( void )
  13. {
  14.     if (_cursesOn) 
  15.         ioTerminate(); 
  16. }
  17.  
  18. /*************************************************************************/
  19.  
  20. volatile sig_atomic_t _signaling = 0;
  21.  
  22. void signalCleanUp (int sig)
  23. {
  24.     if (_signaling) 
  25.         raise (sig);
  26.     _signaling = 1;
  27.  
  28.     cleanUp();
  29.     
  30.     raise (sig);
  31. }
  32.  
  33. /*************************************************************************/
  34. /* returns !=0 if error */
  35.  
  36. int parseOpts(int argc, char *argv[])
  37. {
  38.     int c;
  39.     char hlpmsg[] =
  40.     "Ninux Change Directory 0.9.8 (" __DATE__ ")\n"
  41.     "Copyright (C) 1995  Borja Etxebarria\n"
  42.     "Basque Country University\n"
  43.     "\n"
  44.     "usage: %s [-rRfhHaAvVdDtTxlL?i] [dir]\n"
  45.     " -r -R     force rebuild: on/off(*)\n"
  46.     " -f -h -H  scope area: full/home/auto(*)\n"
  47.     " -a -A     rebuild mode: auto(*)/manual\n"
  48.     " -v -V     verbose: on/off(*)\n"
  49.     " -d -D     dump directory tree: on/interactive(*)\n"
  50.     " -t -T -x  normal text instead of lineart: on/off/auto(*)\n"
  51.     " -l -L     link format: (ldir -> dir)/(ldir@)(*)\n"
  52.     " -? -i     this help\n"
  53.     " dir       direct jump to <dir>\n";
  54.  
  55.     while ((c = getopt(argc, argv, "rRfhHaAvVdDtTxlL?i")) != -1) {
  56.         switch (c) {
  57.         case 'r':
  58.             _rebuild = 1;
  59.             break;
  60.         case 'R':
  61.             _rebuild = 0;
  62.             break;
  63.         case 'f':
  64.             _scope = 1;
  65.             break;
  66.         case 'h':
  67.             _scope = -1;
  68.             break;
  69.         case 'H':
  70.             _scope = 0;
  71.             break;
  72.         case 'v':
  73.             _verbose = 1;
  74.             break;
  75.         case 'V':
  76.             _verbose = 0;
  77.             break;
  78.         case 'a':
  79.             _rebauto = 1;
  80.             break;
  81.         case 'A':
  82.             _rebauto = 0;
  83.             break;
  84.         case 'd':
  85.             _justdump = 1;
  86.             break;
  87.         case 'D':
  88.             _justdump = 0;
  89.             break;
  90.         case 'T':
  91.             _lineart = 1;
  92.             break;
  93.         case 't':
  94.             _lineart = 0;
  95.             break;
  96.         case 'x':
  97.             _lineart = 2;
  98.             break;
  99.         case 'l':
  100.             _showlink = 1;
  101.             break;
  102.         case 'L':
  103.             _showlink = 0;
  104.             break;
  105.         case '?':
  106.         case 'i':
  107.         default:
  108.             fprintf(stderr, hlpmsg, argv[0]);
  109.             return 1;
  110.         }
  111.     }
  112.     return 0;
  113. }
  114.  
  115. /*************************************************************************/
  116. /* returns !=0 if error. Parses NCD_OPTS environment switches, and then
  117.    command line switches */
  118.  
  119. int parseArguments(int argc, char *argv[])
  120. {
  121.     extern int optind;
  122.     int i, ret;
  123.     char *ss[2];
  124.  
  125.     ss[1] = getenv("NCD_OPTS");
  126.     if (ss[1]) {
  127.         i = optind;
  128.         optind = 0;
  129.         if (parseOpts(2, ss))
  130.             return 1;
  131.         optind = i;
  132.     }
  133.     ret = parseOpts(argc, argv);
  134.     
  135.     if ((ret==0)&&(optind<argc)) {
  136.         strcpy(_argumentDir,argv[optind]);
  137.         if (_argumentDir[0]=='/')  {
  138.             if (_scope==0)
  139.                 _scope = 1;
  140.             if (_argumentDir[1]!='\0')
  141.                 strcpy(_argumentDir, _argumentDir+1);
  142.         }
  143.         
  144.         if (_verbose) 
  145.             fprintf(stderr,"command-line dir: %s\n",_argumentDir);
  146.     }                       
  147.     else
  148.         _argumentDir[0]='\0';
  149.                             
  150.     return ret;
  151. }
  152.  
  153. /*************************************************************************/
  154.  
  155. DirNode *rebuildTree(void)
  156. {
  157.     DirNode *rootNode;
  158.     DirNode *dn;
  159.     DirNode homeNode;
  160.  
  161.     if (_cursesOn) 
  162.         cursRebuildMsg();
  163.     else
  164.         fprintf(stderr, "Rebuilding directory tree...");
  165.     if ((_verbose)&&(!_cursesOn))
  166.         fprintf(stderr, "\n");
  167.  
  168.     rootNode = readDirsInNodes(_root, NULL);
  169.  
  170.     if (_scope == 1) {
  171.         dn = searchNodeForDir(rootNode, _root, _xhome);
  172.         if (dn == NULL) {
  173.             cleanUp();
  174.             fprintf(stderr, "error: invalid HOME directory\n");
  175.             exit(1);
  176.         }
  177.         homeNode = *dn;
  178.         homeNode.left = homeNode.up = homeNode.down = NULL;
  179.         homeNode.name = getDirName(_home);
  180.         homeNode.lname = NULL;
  181.  
  182.         writeNodesToFile(_fullFile, rootNode);
  183.         writeNodesToFile(_homeFile, &homeNode);
  184.     }
  185.     else {
  186.         writeNodesToFile(_homeFile, rootNode);
  187.     }
  188.     if (!_cursesOn)
  189.         fprintf(stderr, " done!\n");
  190.  
  191.     return rootNode;
  192. }
  193.  
  194. /*************************************************************************/
  195.  
  196. DirNode *readTreeFiles(void)
  197. {
  198.     DirNode *homeNode, *rootNode;
  199.     DirNode *dn;
  200.  
  201.     if (_rebuild) {
  202.         _rebuild = 0;
  203.         return rebuildTree();
  204.     }
  205.  
  206.     if ((_verbose)&&(!_cursesOn))
  207.         fprintf(stderr, "reading %s...\n", _homeFile);
  208.     rootNode = readNodesFromFile(_homeFile);
  209.  
  210.     if (_scope == 1) {
  211.         homeNode = rootNode;
  212.         if ((_verbose)&&(!_cursesOn))
  213.             fprintf(stderr, "reading %s...\n", _fullFile);
  214.         rootNode = readNodesFromFile(_fullFile);
  215.         dn = searchNodeForDir(rootNode, _root, _xhome);
  216.         if (dn == NULL) {
  217.             if (_rebauto == 0) {
  218.                 cleanUp();
  219.                 fprintf(stderr, "error: %s unusable, please rebuild\n", _fullFile);
  220.                 exit(1);
  221.             }
  222.             else {
  223.                 _rebauto = 0;
  224.                 delNodesFromMemory(homeNode);
  225.                 delNodesFromMemory(rootNode);
  226.                 return rebuildTree();
  227.             }
  228.         }
  229.         delNodesFromMemory(dn->right);
  230.         dn->right = homeNode->right;
  231.         free(homeNode->name);
  232.         if (homeNode->lname)
  233.             free(homeNode->lname);
  234.         *homeNode = *dn;
  235.         if (homeNode->down != NULL)
  236.             (homeNode->down)->up = homeNode;
  237.         if (homeNode->up != NULL)
  238.             (homeNode->up)->down = homeNode;
  239.         else if (homeNode->left != NULL)
  240.             (homeNode->left)->right = homeNode;
  241.         free(dn);
  242.     }
  243.  
  244.     dn = searchNodeForDir(rootNode, _xroot, _cwd);
  245.     if ((dn == NULL) && (_rebauto != 0)) {
  246.         delNodesFromMemory(rootNode);
  247.         return rebuildTree();
  248.     }
  249.  
  250.     return rootNode;
  251. }
  252.  
  253. /*************************************************************************/
  254. /* 1 if cancel */
  255.  
  256. int getFinalPath( DirNode * node )
  257. {
  258.     char * s;
  259.     
  260.     if (node==NULL) 
  261.         return 1;
  262.  
  263.     s = getNodeFullPath(node, 0, 0, NULL, 0);
  264.     if ((_verbose)&&(!_cursesOn))
  265.         fprintf(stderr,"selected directory: %s\n",s);
  266.     strcpy(_finalDir, s);
  267.  
  268.     return 0;
  269. }
  270.  
  271. /*************************************************************************/
  272.  
  273. void changeToFinalDir( void )
  274. {
  275.     FILE * f;
  276.     int len;
  277.     
  278.     len = strlen(_finalDir);
  279.  
  280.     f = fopen(_selDirFile,"w");
  281.     if (f==NULL) {
  282.         cleanUp();
  283.         fprintf(stderr,"error: can't open file %s\n",_selDirFile);
  284.         exit(1);
  285.     }
  286.     if (fprintf(f,"%s",_finalDir)<len) {
  287.         cleanUp();
  288.         fprintf(stderr,"error: can't write file %s\n",_selDirFile);
  289.         exit(1);
  290.     }
  291.     if (fclose(f)!=0) {
  292.         cleanUp();
  293.         fprintf(stderr,"error: can't close file %s\n",_selDirFile);
  294.         exit(1);
  295.     }
  296. }
  297.  
  298. /*************************************************************************/
  299.  
  300. void initializeFinalDir( void )
  301. {
  302.     FILE * f;
  303.     
  304.     strcpy(_finalDir,".");
  305.  
  306.     f = fopen(_selDirFile,"w");
  307.     fprintf(f,"%s",_finalDir);
  308.     fclose(f);
  309. }
  310.  
  311. /*************************************************************************/
  312.  
  313. void getGlobals( int init_cwd )
  314. {
  315.     char *s;
  316.  
  317.     if (init_cwd)
  318.         _cursesOn = 0;
  319.  
  320.     s = getenv("HOME");
  321.     if (s == NULL) {
  322.         cleanUp();
  323.         fprintf(stderr, "error: can't get HOME directory\n");
  324.         exit(1);
  325.     }
  326.     
  327.     strcpy(_home, s);
  328.     addSlash(_home);
  329.     strcpy(_xhome, _home);
  330.  
  331.     if (trueDir(_xhome) == NULL) {
  332.         cleanUp();
  333.         fprintf(stderr, "error: invalid HOME directory\n");
  334.         exit(1);
  335.     }
  336.     if ((_verbose)&&(!_cursesOn))
  337.         fprintf(stderr, "HOME=%s (%s)\n", _home, _xhome);
  338.  
  339.     if (init_cwd) {
  340.         s = getcwd(_cwd, PATH_MAX);
  341.         if (s == NULL) {
  342.             cleanUp();
  343.             fprintf(stderr, "error: can't get current directory\n");
  344.             exit(1);
  345.         }
  346.         addSlash(_cwd);
  347.         if ((_verbose)&&(!_cursesOn))
  348.             fprintf(stderr, "cwd=%s\n", _cwd);
  349.  
  350.         if (_scope == 0) {
  351.             if (strstr(_cwd, _xhome) == _cwd)
  352.                 _scope = -1;
  353.             else
  354.                 _scope = 1;
  355.         }
  356.     }
  357.  
  358.     if (_scope == -1) {
  359.         strcpy(_root, _home);
  360.         strcpy(_xroot, _xhome);
  361.         if ((_verbose)&&(!_cursesOn))
  362.             fprintf(stderr, "scope area: HOME\n");
  363.     }
  364.     else {
  365.         strcpy(_root, "/");
  366.         strcpy(_xroot, _root);
  367.         if ((_verbose)&&(!_cursesOn))
  368.             fprintf(stderr, "scope area: FULL\n");
  369.     }
  370.     strcpy(_homeFile, _home);
  371.     strcpy(_fullFile, _home);
  372.     strcpy(_selDirFile, _home);
  373.     strcat(_homeFile, ".ncd_htree");
  374.     strcat(_fullFile, ".ncd_ftree");
  375.     strcat(_selDirFile, ".ncd_sdir");
  376.     initializeFinalDir();
  377.     
  378.     signal(SIGHUP,signalCleanUp);
  379.     signal(SIGINT,signalCleanUp);
  380.     signal(SIGQUIT,signalCleanUp);
  381.     signal(SIGTERM,signalCleanUp);
  382.     signal(SIGKILL,signalCleanUp);
  383. }
  384.  
  385. /*************************************************************************/
  386.  
  387. int main(int argc, char *argv[])
  388. {
  389.     int quit;
  390.     DirNode * dn;
  391.     int ret;
  392.  
  393.     ret = 1;
  394.  
  395.     if (parseArguments(argc, argv))
  396.         return 1;
  397.  
  398.     getGlobals(1);
  399.  
  400.     _rootNode = readTreeFiles();
  401.  
  402.     if (_rootNode != NULL) {
  403.         numerateNodeTree(_rootNode, 0, 0);
  404.         _lastNode = getLastDescendant(_rootNode);
  405.  
  406.         if (_justdump) {
  407.             showTree(_rootNode);
  408.             ret = 2;
  409.         }
  410.         else if (strlen(_argumentDir)>0) {
  411.             dn = directSelectANode();
  412.             ret = getFinalPath(dn);
  413.         }
  414.         else { 
  415.             do {
  416.                 dn = selectANode(&quit);
  417.                 switch (quit) {
  418.                 case 3:  /* rescan */
  419.                     _rebuild = 1;
  420.                     _scope = -_scope;
  421.                 case 4:  /* scope toggle */
  422.                     _scope = -_scope;
  423.                     if (_scope==-1)
  424.                         _rebauto = 0;
  425.                     delNodesFromMemory(_rootNode);
  426.                     getGlobals(0);
  427.                     _rootNode = readTreeFiles();
  428.                     quit = 0;
  429.                     if (_rootNode != NULL) {
  430.                         numerateNodeTree(_rootNode, 0, 0);
  431.                         _lastNode = getLastDescendant(_rootNode);
  432.                     }
  433.                     else
  434.                         quit = 1;
  435.                     break;
  436.                 case 1:
  437.                     if ((_verbose)&&(!_cursesOn))
  438.                         fprintf(stderr,"operation cancelled by the user!\n");
  439.                 case 2:
  440.                 default:
  441.                     ret = getFinalPath(dn);
  442.                     quit = 1;
  443.                     break;                    
  444.                 }
  445.             } while (!quit);
  446.         }
  447.  
  448.         delNodesFromMemory(_rootNode);
  449.     }
  450.     else
  451.         ret = 1;
  452.     
  453.     changeToFinalDir();
  454.  
  455.     return ret;
  456. }
  457.  
  458. /*************************************************************************/
  459.